package com.atguigu.gmall.service;

import com.alibaba.fastjson.JSONObject;
import com.atguigu.gmall.service.entity.GmallCorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;

import java.util.Date;
import java.util.UUID;

@Component
public class RabbitService {

    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private RedisTemplate redisTemplate;

    //发普通消息
    @GetMapping("/sendMessage")
    public boolean sendMessage(String exchange, String routingKey, Object msg) {
        //创建回调对象  ：为了发消息失败时 重新发送所需的对象
        GmallCorrelationData correlationData = new GmallCorrelationData();

        //交换机,routingKey,消息,ID
        correlationData.setExchange(exchange);
        correlationData.setRoutingKey(routingKey);
        correlationData.setMessage(msg);
        String uuid = UUID.randomUUID().toString();
        correlationData.setId(uuid);

        //借助外力 redis
        String cacheKey = "mq:retry:message";
        redisTemplate.opsForHash().put(cacheKey,uuid, JSONObject.toJSONString(correlationData));

        rabbitTemplate.convertAndSend(exchange, routingKey, msg,correlationData);
        return true;
    }

    //发送死信延迟消息
    public void sendDeadLetterMessage(String exchange, String routingKey, Object msg,
            int time){

        //创建回调对象  ：为了发消息失败时 重新发送所需的对象
        GmallCorrelationData correlationData = new GmallCorrelationData();

        String uuid = UUID.randomUUID().toString();
        correlationData.setId(uuid);
        //交换机,routingKey,消息,ID
        correlationData.setExchange(exchange);
        correlationData.setRoutingKey(routingKey);
        correlationData.setMessage(msg);
        //延迟消息设置
        correlationData.setDelay(true);
        correlationData.setDelayTime(time);

        //借助外力 redis
        String cacheKey = "mq:retry:message";
        redisTemplate.opsForHash().put(cacheKey,uuid,
                JSONObject.toJSONString(correlationData));
        //发延迟消息 基于死信
        rabbitTemplate.convertAndSend(exchange, routingKey, msg,message -> {
            //过期时间 毫秒
            System.out.println("发消息时间：" + new Date());
            message.getMessageProperties().setExpiration(String.valueOf(time*1000));
            return message;
        },correlationData);
    }

    //发送死信延迟消息
    public void sendDelayMessage(String exchange, String routingKey, Object msg, int time) {
        //创建回调对象  ：为了发消息失败时 重新发送所需的对象
        GmallCorrelationData correlationData = new GmallCorrelationData();

        String uuid = UUID.randomUUID().toString();
        correlationData.setId(uuid);
        //交换机,routingKey,消息,ID
        correlationData.setExchange(exchange);
        correlationData.setRoutingKey(routingKey);
        correlationData.setMessage(msg);
        //延迟消息设置
        correlationData.setDelay(true);
        correlationData.setDelayTime(time);

        //是否是插件
        correlationData.setChajian(true);

        //借助外力 redis
        String cacheKey = "mq:retry:message";
        redisTemplate.opsForHash().put(cacheKey,uuid,
                JSONObject.toJSONString(correlationData));
        //发延迟消息 基于插件
        rabbitTemplate.convertAndSend(exchange, routingKey, msg,message -> {
            //====区别：设置延迟时间 毫秒=====
            System.out.println("基于插件发消息时间：" + new Date());
            message.getMessageProperties().setDelay(time*1000);
            return message;
        },correlationData);

    }
}
